<template>
  <el-drawer v-model="drawerVisible" :z-index="1000" :destroy-on-close="true" size="750px" :title="`${drawerProps.title}`">
    <el-form
      ref="deviceKindFormRef"
      label-width="116px"
      label-suffix=" :"
      :inline="true"
      :rules="rules"
      :disabled="drawerProps.isView"
      :model="drawerProps.row"
      :hide-required-asterisk="drawerProps.isView"
    >
      <el-form-item label="教材名称" prop="textbookName">
        <el-input style="width: 190px" v-model="drawerProps.row!.textbookName" placeholder="请填写教材名称" clearable></el-input>
      </el-form-item>
      <el-form-item label="教材类型" prop="textbookType">
        <el-select style="width: 190px" v-model="drawerProps.row!.textbookType" placeholder="请选择教材类型" clearable>
          <el-option v-for="item in textbookType" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="所属设备分类" prop="deviceKindId">
        <el-select
          style="width: 190px"
          v-model="drawerProps.row!.deviceKindId"
          placeholder="请选择设备分类"
          clearable
          @change="_getDeviceSelList"
        >
          <el-option v-for="item in deviceKindSelList" :key="item.kindId" :label="item.kindName" :value="item.kindId" />
        </el-select>
      </el-form-item>
      <el-form-item label="所属柜体" prop="deviceId">
        <el-select
          style="width: 190px"
          v-model="drawerProps.row!.deviceId"
          placeholder="请选择所属柜体"
          :disabled="!drawerProps.row!.deviceKindId"
          clearable
        >
          <el-option v-for="item in deviceSelList" :key="item.deviceId" :label="item.deviceName" :value="item.deviceId" />
        </el-select>
      </el-form-item>
      <el-form-item label="开始时间" prop="startTime">
        <el-date-picker
          style="width: 190px"
          placeholder="请选择开始时间"
          type="datetime"
          format="YYYY-MM-DD HH:mm:ss"
          value-format="YYYY-MM-DD HH:mm:ss"
          v-model="drawerProps.row!.startTime"
        />
      </el-form-item>
      <el-form-item label="结束时间" prop="endTime">
        <el-date-picker
          style="width: 190px"
          placeholder="请选择结束时间"
          type="datetime"
          format="YYYY-MM-DD HH:mm:ss"
          value-format="YYYY-MM-DD HH:mm:ss"
          v-model="drawerProps.row!.endTime"
        />
      </el-form-item>
      <el-form-item label="培训老师" prop="teacherId">
        <el-select style="width: 190px" v-model="drawerProps.row!.teacherId" placeholder="请选择培训老师" clearable>
          <el-option v-for="item in teacherSelList" :key="item.userId" :label="item.userName" :value="item.userId" />
        </el-select>
      </el-form-item>
      <div class="textBookFiles">
        <el-divider content-position="center" v-if="labList?.length">实验</el-divider>
        <div class="labsForm" v-for="(item, index) in labList" :key="item.labId">
          <el-input class="labItem" v-model="item.labName" placeholder="请输入实验名称" clearable></el-input>
          <el-select class="labItem" v-model="item.materialType" placeholder="请选择素材类型" clearable>
            <el-option v-for="val in materialType" :key="val.value" :label="val.label" :value="val.value" />
          </el-select>
          <div v-if="!item.materialFileId">
            <el-upload
              :ref="el => getUploadRef(el, index)"
              :limit="1"
              :on-change="uploadFile => _uploadFile(uploadFile, index)"
              :on-exceed="files => handleExceed(files, index)"
              :auto-upload="false"
              :show-file-list="false"
              :disabled="!item.materialType"
              @click="_clickUploadBtn(index)"
              v-if="!drawerProps.isView"
            >
              <template #trigger>
                <el-button type="text" class="labItem">上传文件</el-button>
              </template>
            </el-upload>
          </div>
          <div style="display: flex; justify-content: space-around; width: 160px" v-else>
            <el-button type="text" @click="_previewFile(index)" v-if="!drawerProps.isView">{{
              item.materialType !== "image" && item.materialType !== "pdf" && item.materialType !== "media"
                ? "下载文件"
                : "预览文件"
            }}</el-button>
            <div class="previewBtn" @click="_previewFile(index)" v-else>
              {{
                item.materialType !== "image" && item.materialType !== "pdf" && item.materialType !== "media"
                  ? "下载文件"
                  : "预览文件"
              }}
            </div>
            <el-upload
              :ref="el => getUploadRef(el, index)"
              :limit="1"
              :on-change="uploadFile => _uploadFile(uploadFile, index)"
              :on-exceed="files => handleExceed(files, index)"
              :auto-upload="false"
              :show-file-list="false"
              :disabled="!item.materialType"
              @click="_clickUploadBtn(index)"
              v-if="!drawerProps.isView"
            >
              <template #trigger>
                <el-button type="text">修改文件</el-button>
              </template>
            </el-upload>
          </div>
          <div class="handleBtnWrap">
            <el-icon class="delBtn" color="var(--el-color-danger)" @click="_removeLab(index)" v-if="!drawerProps.isView">
              <Delete />
            </el-icon>
          </div>
        </div>
        <div class="addBtn">
          <el-button type="primary" :icon="Plus" @click="_addLab" v-if="!drawerProps.isView">新增实验</el-button>
        </div>
        <el-divider content-position="center" v-if="linkList?.length">链接</el-divider>
        <div class="linksForm" v-for="(item, index) in linkList" :key="item.linkId">
          <el-input class="linkItem" v-model="item.linkName" placeholder="请输入链接名称" clearable></el-input>
          <el-select class="linkItem" v-model="item.linkType" placeholder="请选择链接类型" clearable>
            <el-option v-for="val in linkType" :key="val.value" :label="val.label" :value="val.value" />
          </el-select>
          <el-input
            class="linkItem"
            style="width: 190px"
            v-model="item.linkAddress"
            placeholder="请输入链接地址"
            clearable
          ></el-input>
          <div class="handleBtnWrap">
            <el-icon class="delBtn" color="var(--el-color-danger)" @click="_removeLink(index)" v-if="!drawerProps.isView">
              <Delete />
            </el-icon>
            <el-icon class="copyBtn" color="var(--el-color-primary)" v-copy="item.linkAddress"><CopyDocument /></el-icon>
            <a
              class="linkBtn"
              :href="getURL(item.linkAddress)"
              target="_blank"
              rel="noopener noreferrer"
              v-show="item.linkType === 'link' && item.linkAddress"
            >
              <el-icon color="var(--el-color-warning)"><Link /></el-icon>
            </a>
          </div>
        </div>
        <div class="addBtn">
          <el-button type="primary" :icon="Plus" @click="_addLink" v-if="!drawerProps.isView">新增链接</el-button>
        </div>
      </div>
    </el-form>
    <el-dialog v-model="previewVisble1" width="100%" title="预览pdf" :fullscreen="true">
      <div style="height: 80vh">
        <PDFViewer page-scale="page-fit" theme="dark" width="80%" height="100%" :src="PDFSrc" style="margin: 0 auto" />
      </div>
    </el-dialog>

    <el-dialog v-model="previewVisble2" width="100%" title="预览视频" :fullscreen="true">
      <div style="height: 80vh">
        <vue3VideoPlay width="100%" height="100%" :src="videoSrc" />
      </div>
    </el-dialog>

    <el-image-viewer @close="previewVisble = false" :url-list="[previewImgUrl]" v-if="previewVisble" :z-index="99999" />
    <template #footer>
      <el-button @click="_colse">取消</el-button>
      <el-button type="primary" v-show="!drawerProps.isView" @click="handleSubmit">确定</el-button>
    </template>
  </el-drawer>
</template>

<script setup lang="ts" name="DeviceKindDrawer">
import { ref, reactive } from "vue";
import PDFViewer from "@/components/PDFViewer.vue";
import { ElMessage, genFileId, FormInstance } from "element-plus";
import type { UploadInstance, UploadRawFile, UploadFile } from "element-plus";

import { Textbook, ResultData } from "@/api/interface";
import { textbookType } from "@/utils/serviceDict";
import { getURL } from "@/utils/index";
import { uploadFile } from "@/api/modules/common";
import { getDeviceKindSelList } from "@/api/modules/deviceManage/deviceKind";
import { getCabinetSelList } from "@/api/modules/deviceManage/cabinet";
import { getUserSelList } from "@/api/modules/user";
import { Delete, Plus } from "@element-plus/icons-vue";
import { getTextbookDtl } from "@/api/modules/textbookManage/textbookList";
// import { useDownload } from "@/hooks/useDownload";
import { VITE_API_URL } from "@/config/index";
const rules = reactive({
  textbookName: [{ required: true, trigger: "blur", message: "请填写教材名称" }],
  textbookType: [{ required: true, trigger: "blur", message: "请选择教材类型" }],
  deviceKindId: [{ required: true, trigger: "blur", message: "请选择所属设备分类" }],
  deviceId: [{ required: true, trigger: "blur", message: "请选择所属柜体" }],
  startTime: [{ required: true, trigger: "blur", message: "请选择开始时间" }],
  endTime: [{ required: true, trigger: "blur", message: "请选择结束时间" }],
  teacherId: [{ required: true, trigger: "blur", message: "请选择培训老师" }]
});

const materialType = ref([
  {
    label: "PDF文件",
    value: "pdf"
  },
  {
    label: "word文档",
    value: "word"
  },
  {
    label: "图片",
    value: "image"
  },
  {
    label: "视频",
    value: "media"
  }
]);

const linkType = ref([
  {
    label: "超链接地址",
    value: "link"
  },
  {
    label: "目录地址",
    value: "directory"
  },
  {
    label: "应用地址",
    value: "ext"
  }
]);
const deviceKindSelList: any = ref([]);
const deviceSelList: any = ref([]);
const teacherSelList: any = ref([]);
const labList: any = ref([]);
const linkList: any = ref([]);
const uploadRefList = ref<UploadInstance[]>([]);
const textbookMenuList: any = ref([]);
interface DrawerProps {
  title: string;
  isView: boolean;
  row: Partial<Textbook.ResTextbookList>;
  api?: (params: any) => Promise<any>;
  getTableList?: () => void;
  resetTableList?: () => void;
}
const drawerVisible = ref(false);
const previewVisble = ref(false);
const previewVisble1 = ref(false);
const previewVisble2 = ref(false);
const previewImgUrl = ref("");
const previewFileUrl = ref("");
const PDFSrc = ref("");
const videoSrc = ref("");
const textbookDtl: any = ref(null);
const drawerProps = ref<DrawerProps>({
  isView: false,
  title: "",
  row: {}
});
// 接收父组件传过来的参数
const acceptParams = async (params: DrawerProps) => {
  drawerProps.value = params;
  drawerVisible.value = true;
  previewFileUrl.value = "";
  previewImgUrl.value = "";
  previewVisble.value = false;
  linkList.value = [];
  labList.value = [];
  const deviceKindRes: any = (await getDeviceKindSelList({ pageNum: 1, pageSize: 100000000 })).result;
  deviceKindSelList.value = deviceKindRes.dataList;
  const res = await getUserSelList({ userType: "teacher" });
  teacherSelList.value = res.dataList;
  if (drawerProps.value.title !== "新增") {
    try {
      const { result } = (await getTextbookDtl({ textbookId: drawerProps.value.row!.textbookId as number })) as ResultData;
      textbookDtl.value = result;

      labList.value = textbookDtl.value.labList.map((item: any) => {
        return {
          labId: item.labId,
          labName: item.labName,
          materialType: item.materialType,
          materialFileId: item.materialFileId,
          fileUrl: `${VITE_API_URL}/file/download/${item.materialFileId}`
        };
      });
      linkList.value = textbookDtl.value.linkList.map((item: any) => {
        return {
          linkId: item.linkId,
          linkName: item.linkName,
          linkType: item.linkType,
          linkAddress: item.linkAddress
        };
      });
      textbookMenuList.value = [
        {
          id: 1,
          label: textbookDtl.value.textbookName,
          children: labList.value.map((item: any) => {
            return {
              id: item.labId,
              label: item.labName
            };
          })
        }
      ];
    } catch (error) {}
  }
};

// 提交数据（新增/编辑）
const deviceKindFormRef = ref<FormInstance>();

/**
 * 获取上传组件ref集合
 */
const getUploadRef = (el: any, index: number) => {
  if (el) {
    uploadRefList.value[index] = el;
  }
};

/**
 * 预览文件
 */
const _previewFile = (index: number) => {
  switch (labList.value[index].materialType) {
    case "image":
      previewVisble.value = true;
      previewImgUrl.value = labList.value[index].fileUrl;
      break;
    case "pdf":
      previewVisble1.value = true;
      PDFSrc.value = labList.value[index].fileUrl;
      break;
    case "media":
      previewVisble2.value = true;
      videoSrc.value = labList.value[index].fileUrl;
      break;
    default:
      window.open(labList.value[index].fileUrl);
      break;
  }
};
/**
 * 文件上传
 */
const _uploadFile = (file: UploadFile, index: number) => {
  const site = file.name.lastIndexOf("\.");
  const fileName = file.name.substring(0, site);
  const fileSuffix = file.name.substring(site + 1, file.name.length).toLowerCase();
  switch (labList.value[index].materialType) {
    case "pdf":
      if (fileSuffix !== "pdf") {
        ElMessage.error("文件类型不匹配或不支持该种类型文件");
        return false;
      }
      break;
    case "word":
      if (fileSuffix !== "doc" && fileSuffix !== "docx") {
        ElMessage.error("文件类型不匹配或不支持该种类型文件");
        return false;
      }
      break;
    case "image":
      const imgTypelist = ["png", "jpg", "jpeg", "gif"];
      if (!imgTypelist.includes(fileSuffix)) {
        ElMessage.error("文件类型不匹配或不支持该种类型文件");
        return false;
      }
      break;
    case "media":
      const videoTypelist = ["mp4", "webm", "ogg"];
      if (!videoTypelist.includes(fileSuffix)) {
        ElMessage.error("文件类型不匹配或不支持该种类型文件");
        return false;
      }
      break;
    default:
      break;
  }
  filetoBase64(file.raw as File).then(async (base64Value: any) => {
    if (base64Value.indexOf("base64,") != -1) {
      base64Value = base64Value.substr(base64Value.indexOf("base64,") + 7);
    }

    try {
      const res = await uploadFile({
        fileType: "deviceDevOps",
        fileContent: base64Value,
        fileName,
        fileSuffix
      });
      labList.value[index].materialFileId = res.fileId;
      labList.value[index].fileUrl = `${VITE_API_URL}/file/download/${res.fileId}`;
      console.log(labList.value[index].fileUrl);
    } catch (error) {}
  });
};
/**
 * 关闭弹窗
 */
const _colse = () => {
  drawerVisible.value = false;
  deviceKindFormRef.value && deviceKindFormRef.value.resetFields();
};
/**
 * 新增实验
 */
const _addLab = () => {
  const labItem = {
    labName: "",
    materialType: "",
    materialFileId: "",
    fileUrl: ""
  };
  labList.value.push(labItem);
};
/**
 * 新增链接
 */
const _addLink = () => {
  const linkItem = {
    linkName: "",
    linkType: "",
    linkAddress: ""
  };
  linkList.value.push(linkItem);
};
/**
 * 删除链接
 */
const _removeLink = (index: number) => {
  linkList.value.splice(index, 1);
};
/**
 * 删除实验
 */
const _removeLab = (index: number) => {
  labList.value.splice(index, 1);
};
/**
 * 获取柜体选择列表
 */
const _getDeviceSelList = async (kindType: number) => {
  try {
    const { result } = (await getCabinetSelList({ kindType, pageNum: 1, pageSize: 100000000 })) as ResultData;
    deviceSelList.value = result.dataList;
  } catch (error) {}
};

/**
 * 点击上传按钮
 */
const _clickUploadBtn = (index: number) => {
  if (!labList.value[index].materialType) {
    ElMessage.error("请先选择素材类型");
    return false;
  }
};

/**
 * 提交信息
 */
const handleSubmit = () => {
  let isReturn = false;
  deviceKindFormRef.value!.validate(async valid => {
    if (!valid) return false;
    labList.value.forEach((item: any) => {
      console.log(item);
      if (isReturn) return;
      for (let val in item) {
        if (!item[val]) {
          isReturn = true;
        }
      }
    });
    linkList.value.forEach((item: any) => {
      if (isReturn) return;
      for (let val in item) {
        if (!item[val]) {
          isReturn = true;
        }
      }
    });
    if (isReturn) {
      ElMessage.error("请检查实验或链接数据，数据子项不能为空");
      return false;
    }
    const labListFilter = labList.value.map((item: any) => {
      return drawerProps.value.title === "新增"
        ? { labName: item.labName, materialType: item.materialType, materialFileId: item.materialFileId }
        : { labId: item.labId, labName: item.labName, materialType: item.materialType, materialFileId: item.materialFileId };
    });
    try {
      await drawerProps.value.api!({ ...drawerProps.value.row, labList: labListFilter, linkList: linkList.value });
      ElMessage.success({ message: `${drawerProps.value.title}成功！` });
      drawerProps.value.title === "新增" ? drawerProps.value.resetTableList!() : drawerProps.value.getTableList!();
      drawerVisible.value = false;
    } catch (error) {
      console.log(error);
    }
  });
};

const handleExceed = (files: File[], index: number) => {
  uploadRefList.value[index]!.clearFiles();
  const file = files[0] as UploadRawFile;
  file.uid = genFileId();
  uploadRefList.value[index]!.handleStart(file);
};

const filetoBase64 = (file: File) => {
  let reader = new FileReader(); //实例化文件读取对象
  reader.readAsDataURL(file); //将文件读取为 DataURL,也就是base64编码
  return new Promise(reslove => {
    reader.onload = e => {
      //文件读取成功完成时触发
      if (e.target) {
        let dataURL = e.target.result; //获得文件读取成功后的DataURL,也就是base64编码
        reslove(dataURL);
      }
    };
  });
};
defineExpose({
  acceptParams
});
</script>
<style lang="scss" scoped>
.textBookFiles {
  padding: 20px 10px;
}
.linksForm,
.labsForm {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 20px;
  .linkItem {
    width: 190px;
    margin-right: 10px;
  }
  .labItem {
    width: 190px;
    margin-right: 10px;
  }
}
.addBtn {
  padding: 20px 0;
  text-align: center;
}
.handleBtnWrap {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: flex-start;
  .delBtn,
  .copyBtn,
  .linkBtn {
    width: 33.33%;
    cursor: pointer;
  }
}
.textbookInfo {
  display: flex;
  height: 100%;
  .previewCon {
    display: flex;
    flex: 1;
    align-items: center;
    justify-content: center;
    margin-left: 20px;
  }
}
.previewBtn {
  font-size: 14px;
  color: var(--el-color-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
</style>
